package main

import (
	"net"
	"common"
	"strings"
	"memcached"
	"os"
)

var handlers = map[string]func(*memcached.Command, *memcached.Conn, chan<- *memcached.StoreRequest){
	"set":  memcached.HandleSet,
	"get":  memcached.HandleGet,
	"gets": memcached.HandleGet,
}

func handleClient(c *memcached.Conn, out chan<- *memcached.StoreRequest) {
	for {
		s, err := c.ReadLine()
		if err == os.EOF {
			common.Traceln("remote client has closed connection")
			return
		}
		common.Testp(err, "readLine")

		words := strings.Split(s, " ")
		comm := &memcached.Command{
			Name: words[0],
			Args: words[1:],
		}

		if comm.Name == "quit" {
			err := c.Close()
			common.Testp(err, "handleClient c.Close")
			return
		}

		if handler, ok := handlers[comm.Name]; ok {
			handler(comm, c, out)
		} else {
			c.WriteLine("accepted "+s)
		}
	}
}

func main() {
	ch := make(chan *memcached.StoreRequest)
	go memcached.StoreServer(ch)
	l, err := net.Listen("tcp", ":11211")
	common.Teste(err, "main net.Listen")

	for {
		c, err := l.Accept()
		common.Teste(err, "main l.Accept")

		mc := memcached.NewConn(c)
		go common.SafelyDo("handleClient", func() { handleClient(mc, ch) })
	}
}
